package org.gwt.pluginframework.plugin;

import org.gwt.pluginframework.common.Plugin;
import org.gwt.pluginframework.common.event.PluginEvent;

import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.KeyListener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.SplitButton;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.menu.SeparatorMenuItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.ui.Widget;

public class StatusBar extends Plugin implements PerspectiveSouthExtension {

	private static final long serialVersionUID = 1385810108611431740L;
	
	private ContentPanel wrapper;
	
	private ToolBar bar;

	private Menu menu;
	
	private Window customEventInvoker;
	
	private TextField<String> name;
	
	private StatusBarEventInvoker[] items;

	private Button invoke;
	
	public StatusBar() {
		wrapper = new ContentPanel();
		
		wrapper.setHeaderVisible(false);
		wrapper.setBorders(false);
		wrapper.setLayout(new FitLayout());		
	}
	
	private void createCustomEventLauncher() {
		customEventInvoker = new Window();
		customEventInvoker.setHeading("Custome event invoker");
		customEventInvoker.setSize(400, 150);
		customEventInvoker.setLayout(new FitLayout());
		
		FormPanel form = new FormPanel();
		form.setHeaderVisible(false);
		
		name = new TextField<String>();
		name.setFieldLabel("Name");
		name.setAllowBlank(false);
		
		final SelectionListener<ButtonEvent> invokeSelectionListener = new SelectionListener<ButtonEvent>() {
			@Override
			public void componentSelected(ButtonEvent ce) {
				getPluginManager().dispatch(new PluginEvent(name.getValue(), StatusBar.this));
				name.setValue("");
				customEventInvoker.hide();
			}
		};
		
		name.addKeyListener(new KeyListener() {
			@Override
			public void componentKeyPress(ComponentEvent event) {
				switch(event.getKeyCode()) {
				case 10:
				case 13:
						invokeSelectionListener.componentSelected(new ButtonEvent(invoke));
					break;
				}
				super.componentKeyPress(event);
			}	
		});
		form.add(name);
		
		invoke = new Button("Invoke", invokeSelectionListener);
		form.addButton(invoke);
		
		form.addButton(new Button("Cancel", new SelectionListener<ButtonEvent>() {
			@Override
			public void componentSelected(ButtonEvent ce) {
				name.setValue("");
				customEventInvoker.hide();
			}
		}));
		
		customEventInvoker.add(form);
	}
	
	@Override
	public void onInitialize() {
		bar = new ToolBar();
		Button eventConsole = new Button("Event Console", new SelectionListener<ButtonEvent>() {
			@Override
			public void componentSelected(ButtonEvent ce) {
				getPluginManager().dispatch(new PluginEvent(CustomEvents.START_EVENT_CONSOLE, StatusBar.this));
			}
		});
		bar.add(eventConsole);
		Button pluginMonitor = new Button("Plugin Monitor", IconHelper.createStyle("icon-plugin"));
	    pluginMonitor.addSelectionListener(new SelectionListener<ButtonEvent>() {
			@Override
			public void componentSelected(ButtonEvent ce) {
				manager.dispatch(new PluginEvent(CustomEvents.SHOW_PLUGIN_MONITOR_EVENT, StatusBar.this));
			}
	    });
	    bar.add(pluginMonitor);
	    SplitButton eventInvoker = new SplitButton("Event invoker");
	    eventInvoker.setIconStyle("icon-list-items");  
	  
	    menu = new Menu();
	    MenuItem mi = new MenuItem("<b>Custom ...</b>");
	    mi.addSelectionListener(new SelectionListener<MenuEvent>() {
			@Override
			public void componentSelected(MenuEvent ce) {
				if(customEventInvoker == null) {
					createCustomEventLauncher();
				}
				customEventInvoker.show();
				name.focus();
			}
	    });
	    menu.add(mi);  
	    menu.add(new SeparatorMenuItem());
	    
	    if(items != null) {
			for(final StatusBarEventInvoker invoker : items) {
				MenuItem m = new MenuItem(invoker.getLabel());
				m.addSelectionListener(new SelectionListener<MenuEvent>() {
					@Override
					public void componentSelected(MenuEvent ce) {
						getPluginManager().dispatch(invoker.getPluginEvent());
					}
				});
				menu.add(m);
			}
	    }
	    
	    eventInvoker.setMenu(menu);  
	  
	    pluginMonitor.addSelectionListener(new SelectionListener<ButtonEvent>() {
			@Override
			public void componentSelected(ButtonEvent ce) {
				manager.dispatch(new PluginEvent(CustomEvents.SHOW_PLUGIN_MONITOR_EVENT, StatusBar.this));
			}
	    });
	    bar.add(eventInvoker);
		wrapper.add(bar);
	}
	
	public Widget getWidget() {
		return wrapper;
	}

	public String getName() {
		return "StatusBar";
	}

	public void setupManifest() {
		manifest.setName("StatusBar");
		manifest.setVersion("1.0");
	}
	
	/**
	 * Used for injecting custome defined events.
	 * 
	 * @param menu
	 */
	public void registerStatusBarEventInvokers(StatusBarEventInvoker[] items) {
		this.items = items;
	}
}
